// JScript source code

var HID = require('node-hid');
const sm3 = require('sm3');

var GETVERSION = 0x01;
var GETID = 0x02;
var GETVEREX = 0x05;
var CAL_TEA = 0x08;
var SET_TEAKEY = 0x09;
var READBYTE = 0x10;
var WRITEBYTE = 0x11;
var YTREADBUF = 0x12;
var YTWRITEBUF = 0x13;
var MYRESET = 0x20;
var YTREBOOT = 0x24;
var SET_ECC_PARA = 0x30;
var GET_ECC_PARA = 0x31;
var SET_ECC_KEY = 0x32;
var GET_ECC_KEY = 0x33;
var MYENC = 0x34;
var MYDEC = 0x35;
var SET_PIN = 0x36;
var GEN_KEYPAIR = 0x37;
var YTVERIFY = 0x52;
var GET_CHIPID = 0x53;

//errcode
var FAILEDGENKEYPAIR = -21;
var FAILENC = -22;
var FAILDEC = -23;
var FAILPINPWD = -24;
var USBStatusFail = -50;
var ERR_SET_REPORT = -94;
var ERR_GET_REPORT = -93;

var MAX_LEN = 2031;

var SM2_ADDBYTE = 97; //
var MAX_ENCLEN = 128; //
var MAX_DECLEN = MAX_ENCLEN + SM2_ADDBYTE; //
var SM2_USENAME_LEN = 80; //

var ECC_MAXLEN = 32;
var PIN_LEN = 16;

var MAX_TRANSE_LEN = 21;
var SM2_MAX_TRANSE_LEN = 255;

var ID_LEN = 16;

class SoftKey {
  SoftKey() {
    //connection object
    SoftKey.connection = null;
  }

  GetLastError() {
    return this.lasterror;
  }

  StrEnc(InString, Key) {
    var n;
    var m;
    var nlen;

    var b = Buffer.from(InString);
    var zero_buf = Buffer.from([0]);
    b = Buffer.concat([b, zero_buf]);
    nlen = b.length;
    if (b.length < 8) {
      nlen = 8;
    }

    var outb = Buffer.alloc(nlen);
    var inb = Buffer.alloc(nlen);
    b.copy(inb); //如果少于8，则会补0，这里主要是用于补0
    b.copy(outb);

    for (n = 0; n <= nlen - 8; n = n + 8) {
      var tmpoutb = this.sub_EnCode(inb, n, Key);
      for (m = 0; m < 8; m++) {
        outb[m + n] = tmpoutb[m];
      }
    }

    return outb.toString('hex');
  }

  StrDec(
    InString,
    Key, //
  ) {
    var n, m;
    var inb = new Buffer(InString, 'hex');
    var outb = Buffer.alloc(inb.length);
    inb.copy(outb);

    for (n = 0; n <= inb.length - 8; n = n + 8) {
      var tmpoutb = this.sub_DeCode(inb, n, Key);
      for (m = 0; m < 8; m++) {
        outb[m + n] = tmpoutb[m];
      }
    }

    return outb.toString();
  }

  EnCode(inb, Key) {
    this.sub_EnCode(inb, 0, Key);
  }

  sub_EnCode(inb, pos, Key) {
    var cnDelta, y, z, a, b, c, d;
    var outb = new Uint8Array(8);
    var n, i, nlen;
    var sum;
    var temp, temp_1;

    var buf = new Array(16);
    var temp_string;

    cnDelta = 2654435769;
    sum = 0;

    nlen = Key.length;
    i = 0;
    for (n = 1; n <= nlen; n = n + 2) {
      temp_string = Key.substring(n - 1, n - 1 + 2);
      buf[i] = this.HexToInt(temp_string);
      i = i + 1;
    }
    a = 0;
    b = 0;
    c = 0;
    d = 0;
    for (n = 0; n <= 3; n++) {
      a = (buf[n] << (n * 8)) | a;
      b = (buf[n + 4] << (n * 8)) | b;
      c = (buf[n + 4 + 4] << (n * 8)) | c;
      d = (buf[n + 4 + 4 + 4] << (n * 8)) | d;
    }

    y = 0;
    z = 0;
    for (n = 0; n <= 3; n++) {
      y = (inb[n + pos] << (n * 8)) | y;
      z = (inb[n + 4 + pos] << (n * 8)) | z;
    }

    n = 32;

    while (n > 0) {
      sum = cnDelta + sum;

      temp = (z << 4) & 0xffffffff;

      temp = (temp + a) & 0xffffffff;
      temp_1 = (z + sum) & 0xffffffff;
      temp = (temp ^ temp_1) & 0xffffffff;
      temp_1 = (z >>> 5) & 0xffffffff;
      temp_1 = (temp_1 + b) & 0xffffffff;
      temp = (temp ^ temp_1) & 0xffffffff;
      temp = (temp + y) & 0xffffffff;
      y = temp & 0xffffffff;
      // y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);

      temp = (y << 4) & 0xffffffff;
      temp = (temp + c) & 0xffffffff;
      temp_1 = (y + sum) & 0xffffffff;
      temp = (temp ^ temp_1) & 0xffffffff;
      temp_1 = (y >>> 5) & 0xffffffff;
      temp_1 = (temp_1 + d) & 0xffffffff;
      temp = (temp ^ temp_1) & 0xffffffff;
      temp = (z + temp) & 0xffffffff;
      z = temp & 0xffffffff;
      //  z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);

      n = n - 1;
    }

    for (n = 0; n <= 3; n++) {
      outb[n] = (y >>> (n * 8)) & 255;
      outb[n + 4] = (z >>> (n * 8)) & 255;
    }
    return outb;
  }

  DeCode() {
    sub_DeCode(inb, 0, Key);
  }

  sub_DeCode(inb, pos, Key) {
    var cnDelta, y, z, a, b, c, d;
    var outb = new Uint8Array(8);
    var n, i, nlen;
    var sum;
    var temp, temp_1;

    var buf = new Array(16);
    var temp_string;

    cnDelta = 2654435769;
    sum = 3337565984;

    nlen = Key.length;
    i = 0;
    for (n = 1; n <= nlen; n = n + 2) {
      temp_ = Key.substring(n - 1, n - 1 + 2);
      buf[i] = this.HexToInt(temp_string);
      i = i + 1;
    }
    a = 0;
    b = 0;
    c = 0;
    d = 0;
    for (n = 0; n <= 3; n++) {
      a = (buf[n] << (n * 8)) | a;
      b = (buf[n + 4] << (n * 8)) | b;
      c = (buf[n + 4 + 4] << (n * 8)) | c;
      d = (buf[n + 4 + 4 + 4] << (n * 8)) | d;
    }

    y = 0;
    z = 0;
    for (n = 0; n <= 3; n++) {
      y = (inb[n + pos] << (n * 8)) | y;
      z = (inb[n + 4 + pos] << (n * 8)) | z;
    }

    n = 32;

    while (n > 0) {
      temp = (y << 4) & 0xffffffff;
      temp = (temp + c) & 0xffffffff;
      temp_1 = (y + sum) & 0xffffffff;
      temp = (temp ^ temp_1) & 0xffffffff;
      temp_1 = (y >>> 5) & 0xffffffff;
      temp_1 = (temp_1 + d) & 0xffffffff;
      temp = (temp ^ temp_1) & 0xffffffff;
      temp = (z - temp) & 0xffffffff;
      z = temp & 0xffffffff;
      //  z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);

      temp = (z << 4) & 0xffffffff;
      temp = (temp + a) & 0xffffffff;
      temp_1 = (z + sum) & 0xffffffff;
      temp = (temp ^ temp_1) & 0xffffffff;
      temp_1 = (z >>> 5) & 0xffffffff;
      temp_1 = (temp_1 + b) & 0xffffffff;
      temp = (temp ^ temp_1) & 0xffffffff;
      temp = (y - temp) & 0xffffffff;
      y = temp & 0xffffffff;
      // y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);

      sum = sum - cnDelta;
      n = n - 1;
    }

    for (n = 0; n <= 3; n++) {
      outb[n] = (y >>> (n * 8)) & 255;
      outb[n + 4] = (z >>> (n * 8)) & 255;
    }
    return outb;
  }

  MacthUKeyID(mDevices) {
    if (
      (mDevices.vendorId == SoftKey.VID && mDevices.productId == SoftKey.PID) ||
      (mDevices.vendorId == SoftKey.VID_NEW &&
        mDevices.productId == SoftKey.PID_NEW) ||
      (mDevices.vendorId == SoftKey.VID_NEW_2 &&
        mDevices.productId == SoftKey.PID_NEW_2)
    ) {
      return true;
    }
    return false;
  }

  /////////////////////
  AddZero(InKey) {
    var nlen;
    var n;
    nlen = InKey.length;
    for (n = nlen; n <= 7; n++) {
      InKey = '0' + InKey;
    }
    return InKey;
  }

  myconvert(HKey, LKey) {
    HKey = this.AddZero(HKey);
    LKey = this.AddZero(LKey);
    var out_data = new Uint8Array(8);
    var n;
    for (n = 0; n <= 3; n++) {
      out_data[n] = this.HexToInt(HKey.substring(n * 2, n * 2 + 2));
    }
    for (n = 0; n <= 3; n++) {
      out_data[n + 4] = this.HexToInt(LKey.substring(n * 2, n * 2 + 2));
    }
    return out_data;
  }

  ////bin2hex  & hex2bin
  ByteArrayToHexString(Inb, len) {
    var outstring = '';
    for (var n = 0; n <= len - 1; n++) {
      outstring = outstring + this.myhex(Inb[n]);
    }
    return outstring;
  }

  HexStringToByteArray(InString) {
    var nlen;
    var retutn_len;
    var n, i;
    var b;
    var temp;
    nlen = InString.length;
    if (nlen < 16) retutn_len = 16;
    retutn_len = nlen / 2;
    b = new Uint8Array(retutn_len);
    i = 0;
    for (n = 0; n < nlen; n = n + 2) {
      temp = InString.substring(n, n + 2);
      b[i] = this.HexToInt(temp);
      i = i + 1;
    }
    return b;
  }

  ////////

  //decimal to hex && hex2dec
  myhex(value) {
    if (value < 16) return '0' + value.toString(16);
    return value.toString(16);
  }

  HexToInt(s) {
    var hexch = '0123456789ABCDEF';
    var i, j;
    var r, n, k;
    var ch;
    s = s.toUpperCase();

    k = 1;
    r = 0;
    for (i = s.length; i > 0; i--) {
      ch = s.substring(i - 1, i - 1 + 1);
      n = 0;
      for (j = 0; j < 16; j++) {
        if (ch == hexch.substring(j, j + 1)) {
          n = j;
        }
      }
      r += n * k;
      k *= 16;
    }
    return r;
  }

  ////////////////

  /////////////// send cmd only ,no carry data
  SendNoWithData(CmdFlag) {
    var array_in = new Uint8Array(MAX_TRANSE_LEN);
    this.SendWithData(CmdFlag, array_in);
    return this.lasterror;
  }

  ///////////////////////////
  /*SendWithDataNoErr(CmdFlag,array_in,KeyPath) {

        this.lasterror=0;
        var featureReport = [2, 0];

        featureReport[1] = CmdFlag;

        for (var i = 1; i < array_in.length; i++) {
            featureReport[i + 1] =array_in[i];
        }
        if(KeyPath==null)
        {
            this.lasterror= -92;
            return array_out;
        }
        this.connection = new  HID.HID(KeyPath)
        if(this.connection==null)
        {
            this.lasterror= -92;
            return array_out;
        }
        var Outlen=this.connection.sendFeatureReport( featureReport);
        if(Outlen<2) {this.connection.close();this.lasterror= ERR_SET_REPORT;return undefined;}
        var array_out=this.connection.getFeatureReport(1,SM2_MAX_TRANSE_LEN) ;
        this.connection.close();
        if(array_out.length<1){this.lasterror=ERR_GET_REPORT; return undefined;}

        return array_out;

    }*/

  ///////////send cmd and data
  SendWithDataNoErr(CmdFlag, array_in, KeyPath) {
    this.lasterror = 0;
    var featureReport = [2];
    for (var n = 1; n <= SM2_MAX_TRANSE_LEN + 1; n++) {
      featureReport[n] = 0;
    }

    featureReport[1] = CmdFlag;

    for (var i = 1; i < array_in.length; i++) {
      featureReport[i + 1] = array_in[i];
    }
    if (KeyPath == null) {
      this.lasterror = -92;
      return array_out;
    }
    this.connection = new HID.HID(KeyPath);
    if (this.connection == null) {
      this.lasterror = -92;
      return array_out;
    }
    var Outlen = this.connection.sendFeatureReport(featureReport);
    if (Outlen < 2) {
      this.connection.close();
      this.lasterror = ERR_SET_REPORT;
      return undefined;
    }
    var array_out = this.connection.getFeatureReport(1, 510);
    this.connection.close();
    if (array_out.length < 1) {
      this.lasterror = ERR_GET_REPORT;
      return undefined;
    }

    return array_out;
  }

  SendWithData(CmdFlag, array_in, KeyPath) {
    var array_out = this.SendWithDataNoErr(CmdFlag, array_in, KeyPath);

    if (array_out[0] != 0) {
      this.lasterror = array_out[0] - 256;
    } else {
      this.lasterror = 0;
    }

    return array_out;
  }

  ///////////////
  GetOneByteDataFromUsbKey(cmd, KeyPath) {
    var array_in = new Uint8Array(MAX_TRANSE_LEN);
    var array_out;
    array_out = this.SendWithDataNoErr(cmd, array_in, KeyPath);
    if (this.lasterror) return undefined;
    return array_out[0];
  }

  ////////

  FindPort(start) {
    this.lasterror = 0;
    var KeyPath = '';
    var count = 0;
    var devices = HID.devices();
    devices.forEach((mDevice) => {
      if (this.MacthUKeyID(mDevice)) {
        if (count == start) {
          KeyPath = mDevice.path;
          return KeyPath;
        }
        count++;
      }
    });
    if (KeyPath != '') {
      this.lasterror = 0;
    } else {
      this.lasterror = -92;
    }
    return KeyPath;
  }

  ////////////////////////////////////////////////////////////////////////////////////

  NT_GetIDVersionEx(KeyPath) {
    return this.GetOneByteDataFromUsbKey(5, KeyPath);
  }

  NT_GetIDVersion(KeyPath) {
    return this.GetOneByteDataFromUsbKey(1, KeyPath);
  }

  /////

  GetID(KeyPath) {
    var IDInfo = {
      ID_1: '',
      ID_2: '',
    };
    var array_in = new Uint8Array(MAX_TRANSE_LEN);
    var array_out;
    var t1 = new Buffer.alloc(4);
    var t2 = new Buffer.alloc(4);
    array_out = this.SendWithDataNoErr(2, array_in, KeyPath);
    if (this.lasterror != 0) {
      return '';
    }
    t1[0] = array_out[0];
    t1[1] = array_out[1];
    t1[2] = array_out[2];
    t1[3] = array_out[3];
    t2[0] = array_out[4];
    t2[1] = array_out[5];
    t2[2] = array_out[6];
    t2[3] = array_out[7];
    IDInfo.ID_1 = t1.toString('hex');
    IDInfo.ID_2 = t2.toString('hex');
    return IDInfo;
  }

  GetChipID(KeyPath) {
    var array_in = new Uint8Array(SM2_MAX_TRANSE_LEN);
    var array_out;

    var OutChipID = '';
    var outb = new Uint8Array(ID_LEN);

    array_out = this.SendWithDataNoErr(GET_CHIPID, array_in, KeyPath);
    if (this.lasterror != 0) {
      return '';
    }
    if (array_out[0] != 0x20) {
      this.lasterror = USBStatusFail;
      return OutChipID;
    }

    outb = array_out.slice(1, ID_LEN + 1);

    OutChipID = this.ByteArrayToHexString(outb, 16);
    OutChipID = OutChipID.toUpperCase();
    return OutChipID;
  }

  ////////

  /////
  FindPort_2(start, in_data, verf_data) {
    var n;
    var count = 0;
    var out_data = 0;
    for (n = 0; n < 256; n++) {
      var KeyPath = this.FindPort(n);
      if (this.lasterror != 0) return null;
      out_data = this.sWriteEx(in_data, KeyPath);
      if (this.lasterror != 0) return null;
      if (out_data == verf_data) {
        if (start == count) return KeyPath;
        count++;
      }
    }
    return null;
  }

  SetWritePassword(W_HKey, W_LKey, new_HKey, new_LKey, KeyPath) {
    var address;
    var ary1 = this.myconvert(W_HKey, W_LKey);
    var ary2 = this.myconvert(new_HKey, new_LKey);
    address = 504;

    this.lasterror = this.Sub_WriteByte(ary2, address, 8, ary1, 0, KeyPath);

    return this.lasterror;
  }

  SetReadPassword(W_HKey, W_LKey, new_HKey, new_LKey, KeyPath) {
    var address;
    var ary1 = this.myconvert(W_HKey, W_LKey);
    var ary2 = this.myconvert(new_HKey, new_LKey);
    address = 496;

    this.lasterror = this.Sub_WriteByte(ary2, address, 8, ary1, 0, KeyPath);

    return this.lasterror;
  }

  NT_SetCal(cmd, indata, IsHi, pos, KeyPath) {
    var array_in = new Uint8Array(MAX_TRANSE_LEN);
    var n;
    array_in[1] = IsHi;
    for (n = 0; n < 8; n++) {
      array_in[2 + n] = indata[n + pos];
    }

    var array_out = this.SendWithData(cmd, array_in, KeyPath);
    if (this.lasterror != 0) return this.lasterror;
    if (array_out[0] != 0) {
      this.lasterror = -82;
    }
    return this.lasterror;
  }

  Sub_SetCal(cmd, Key, KeyPath) {
    var KeyBuf = this.HexStringToByteArray(Key);
    this.lasterror = this.NT_SetCal(cmd, KeyBuf, 0, 8, KeyPath);
    if (this.lasterror != 0) return this.lasterror;
    return this.NT_SetCal(cmd, KeyBuf, 1, 0, KeyPath);
  }

  SetCal_2(Key, KeyPath) {
    return this.Sub_SetCal(SET_TEAKEY, Key, KeyPath);
  }

  SetCal_New(Key, KeyPath) {
    return this.Sub_SetCal(13, Key, KeyPath);
  }

  Sub_EncString(cmd, InString, KeyPath) {
    var n;
    var m;
    var nlen;

    var b = Buffer.from(InString);
    var zero_buf = Buffer.from([0]);
    b = Buffer.concat([b, zero_buf]);
    nlen = b.length;
    if (b.length < 8) {
      nlen = 8;
    }

    var outb = Buffer.alloc(nlen);
    var inb = Buffer.alloc(nlen);
    b.copy(inb); //如果少于8，则会补0，这里主要是用于补0
    b.copy(outb);

    for (n = 0; n <= nlen - 8; n = n + 8) {
      var tmpoutb = this.NT_Cal(cmd, inb, n, KeyPath);
      for (m = 0; m < 8; m++) {
        outb[m + n] = tmpoutb[m];
      }
      if (this.lasterror != 0) '';
    }

    return outb.toString('hex');
  }

  EncString(InString, KeyPath) {
    return this.Sub_EncString(8, InString, KeyPath);
  }

  EncString_New(InString, KeyPath) {
    return this.Sub_EncString(12, InString, KeyPath);
  }

  NT_Cal(cmd, InBuf, pos, KeyPath) {
    var n;
    var array_in = new Uint8Array(MAX_TRANSE_LEN);
    var outbuf = new Uint8Array(8);
    for (n = 1; n <= 8; n++) {
      array_in[n] = InBuf[n - 1 + pos];
    }
    var array_out = this.SendWithDataNoErr(cmd, array_in, KeyPath);
    if (this.lasterror != 0) return undefined;
    for (n = 0; n < 8; n++) {
      outbuf[n + pos] = array_out[n];
    }
    if (array_out[8] != 0x55) {
      this.lasterror = -20;
    }
    return outbuf;
  }

  Cal(Inbuf, KeyPath) {
    return this.NT_Cal(8, Inbuf, 0, KeyPath);
  }

  Cal_New(Inbuf, KeyPath) {
    return this.NT_Cal(12, Inbuf, 0, KeyPath);
  }

  SimpleCalData(cmd, in_data, KeyPath) {
    var t1;
    var t2;
    var t3;
    var t4;
    var array_in = new Uint8Array(MAX_TRANSE_LEN);
    array_in[1] = in_data & 255;
    array_in[2] = (in_data >> 8) & 255;
    array_in[3] = (in_data >> 16) & 255;
    array_in[4] = (in_data >> 24) & 255;

    var array_out;
    array_out = this.SendWithDataNoErr(cmd, array_in, KeyPath);
    if (this.lasterror != 0) {
      return 0;
    }
    t1 = array_out[0];
    t2 = array_out[1];
    t3 = array_out[2];
    t4 = array_out[3];

    return t1 | (t2 << 8) | (t3 << 16) | (t4 << 24);
  }

  sWriteEx(in_data, KeyPath) {
    return this.SimpleCalData(0x03, in_data, KeyPath);
  }

  sWrite_2Ex(in_data, KeyPath) {
    return this.SimpleCalData(0x04, in_data, KeyPath);
  }

  /////////////////////
  Sub_WriteByte(indata, address, nlen, password, pos, KeyPath) {
    var array_in = new Uint8Array(MAX_TRANSE_LEN);
    var addr_l;
    var addr_h;
    var n;
    if (address + nlen - 1 > MAX_LEN + 17 || address < 0) return -81;
    addr_h = (address >> 8) * 2;
    addr_l = address & 255;

    array_in[1] = addr_h;
    array_in[2] = addr_l;
    array_in[3] = nlen;

    for (n = 0; n <= 7; n++) {
      array_in[4 + n] = password[n];
    }
    for (n = 0; n < nlen; n++) {
      array_in[12 + n] = indata[n + pos];
    }

    var array_out = this.SendWithDataNoErr(0x13, array_in, KeyPath);
    if (this.lasterror != 0) return this.lasterror;
    if (array_out[0] != 0) {
      this.lasterror = -82;
    }
    return this.lasterror;
  }

  //////////////

  Sub_ReadByte(address, nlen, password, KeyPath) {
    var outData = new Uint8Array(nlen);
    var array_out;
    var ret;
    if (nlen > MAX_TRANSE_LEN) {
      this.lasterror = ERR_OVER_SEC_MAX_LEN;
      return outData;
    }
    if (address + nlen > MAX_LEN) {
      this.lasterror == ERR_OVER_SEC_MAX_LEN;
      return outData;
    }

    var array_in = new Uint8Array(MAX_TRANSE_LEN);
    var addr_l;
    var addr_h;
    var n;

    addr_h = (address >> 8) * 2;
    addr_l = address & 255;

    array_in[1] = addr_h;
    array_in[2] = addr_l;
    array_in[3] = nlen;

    for (n = 0; n <= 7; n++) {
      array_in[4 + n] = password[n];
    }

    array_out = this.SendWithDataNoErr(0x12, array_in, KeyPath);
    if (this.lasterror != 0) return undefined;
    if (array_out[0] != 0) {
      this.lasterror = -82;
      return outData;
    }
    for (n = 0; n < nlen; n++) {
      outData[n] = array_out[n + 1];
    }
    return outData;
  }

  /////////////////////////////
  YWriteEx(indata, address, nlen, HKey, LKey, KeyPath) {
    var ret = 0;
    var n,
      trashLen = 16;

    if (address + nlen - 1 > MAX_LEN || address < 0) return -81;

    trashLen = trashLen - 8;

    var password = this.myconvert(HKey, LKey);
    var tmplen;
    var pos = 0;
    while (nlen > 0) {
      if (nlen > trashLen) tmplen = trashLen;
      else tmplen = nlen;
      this.lasterror = this.Sub_WriteByte(
        indata,
        address + pos,
        tmplen,
        password,
        pos,
        KeyPath,
      );
      if (this.lasterror != 0) {
        return this.lasterror;
      }
      nlen = nlen - trashLen;
      pos = pos + trashLen;
    }

    return this.lasterror;
  }

  ///////////////////////////////
  YWriteString(InString, Address, HKey, LKey, KeyPath) {
    var Buf = Buffer.from(InString);
    this.YWriteEx(Buf, Address, Buf.length, HKey, LKey, KeyPath);
    if (this.lasterror < 0) return this.lasterror;
    return Buf.length;
  }

  ///////////////
  YReadEx(address, nlen, HKey, LKey, KeyPath) {
    var ret = 0;
    var password = new Uint8Array(8);
    var n,
      trashLen = 16;
    var OutData = Buffer.alloc(0);
    var tmp_OutData;

    if (address + nlen - 1 > MAX_LEN || address < 0) return -81;

    password = this.myconvert(HKey, LKey);
    var tmplen;
    var pos = 0;
    while (nlen > 0) {
      if (nlen > trashLen) tmplen = trashLen;
      else tmplen = nlen;
      tmp_OutData = this.Sub_ReadByte(address + pos, tmplen, password, KeyPath);
      if (this.lasterror != 0) {
        return OutData;
      }
      OutData = Buffer.concat([OutData, tmp_OutData]);
      nlen = nlen - trashLen;
      pos = pos + trashLen;
    }

    return OutData;
  }

  //////////////

  YReadString(Address, nlen, HKey, LKey, KeyPath) {
    var outData = this.YReadEx(Address, nlen, HKey, LKey, KeyPath);

    return outData.toString();
  }

  ///////////////////////////////////////////////////// other api
  NT_ReSet(KeyPath) {
    var array_in = new Uint8Array(MAX_TRANSE_LEN);
    var array_out = this.SendWithDataNoErr(MYRESET, array_in, KeyPath);
    if (this.lasterror != 0) return this.lasterror;
    if (array_out[0] != 0) {
      this.lasterror = -82;
    }
    return this.lasterror;
  }

  ReSet(KeyPath) {
    this.lasterror = this.NT_ReSet(KeyPath);
    return this.lasterror;
  }

  y_setcal(indata, password, KeyPath) {
    var n;
    var array_in = new Uint8Array(MAX_TRANSE_LEN);

    array_in[1] = 0;
    array_in[2] = 0;
    array_in[3] = 8;
    for (n = 0; n <= 7; n++) {
      array_in[4 + n] = password[n];
    }
    for (n = 0; n < 8; n++) {
      array_in[12 + n] = indata[n];
    }
    var array_out = this.SendWithDataNoErr(6, array_in, KeyPath);
    if (this.lasterror) return this.lasterror;
    if (array_out[0] != 0) {
      this.lasterror = -82;
    }
    return this.lasterror;
  }

  SetCal(HKey, LKey, new_HKey, new_LKey, KeyPath) {
    var ary1 = this.myconvert(HKey, LKey);
    var ary2 = this.myconvert(new_HKey, new_LKey);

    this.lasterror = this.y_setcal(ary2, ary1, KeyPath);

    return this.lasterror;
  }

  NT_SetID(InBuf, KeyPath) {
    var n;
    var array_in = new Uint8Array(MAX_TRANSE_LEN);
    for (n = 1; n <= 8; n++) {
      array_in[n] = InBuf[n - 2];
    }
    var array_out = this.SendWithDataNoErr(7, array_in, KeyPath);
    if (this.lasterror != 0) return this.lasterror;
    if (array_out[0] != 0) {
      this.lasterror = -82;
    }
    return this.lasterror;
  }

  SetID(Seed, KeyPath) {
    var KeyBuf = this.HexStringToByteArray(Seed);

    return this.NT_SetID(KeyBuf, KeyPath);
  }

  GetProduceDate(KeyPath) {
    var n;
    var array_in = new Uint8Array(MAX_TRANSE_LEN);
    var OutProduceDate = Buffer.alloc(8);
    var array_out = this.SendWithDataNoErr(15, array_in, KeyPath);
    if (this.lasterror != 0) return this.lasterror;
    for (n = 0; n < 8; n++) {
      OutProduceDate[n] = array_out[n];
    }
    return OutProduceDate.toString('hex');
  }

  SetHidOnly(IsHidOnly, KeyPath) {
    return this.NT_SetHidOnly(IsHidOnly, KeyPath);
  }

  NT_SetHidOnly(IsHidOnly, KeyPath) {
    var array_in = new Uint8Array(MAX_TRANSE_LEN);

    if (IsHidOnly) array_in[1] = 0;
    else array_in[1] = 0xff;
    var array_out = this.SendWithDataNoErr(0x55, array_in, KeyPath);
    if (this.lasterror != 0) return this.lasterror;
    if (array_out[0] != 0) {
      return -82;
    }
    return 0;
  }

  SetUReadOnly(KeyPath) {
    return this.NT_SetUReadOnly(KeyPath);
  }

  NT_SetUReadOnly(KeyPath) {
    var array_in = new Uint8Array(MAX_TRANSE_LEN);
    var array_out = this.SendWithDataNoErr(0x56, array_in, KeyPath);
    if (this.lasterror != 0) return this.lasterror;
    if (array_out[0] != 0) {
      return -82;
    }
    return 0;
  }

  NT_Set_SM2_KeyPair(PriKey, PubKeyX, PubKeyY, sm2_UerName, KeyPath) {
    var array_in = new Uint8Array(SM2_MAX_TRANSE_LEN);
    var n = 0;

    for (n = 0; n < ECC_MAXLEN; n++) {
      array_in[1 + n + ECC_MAXLEN * 0] = PriKey[n];
      array_in[1 + n + ECC_MAXLEN * 1] = PubKeyX[n];
      array_in[1 + n + ECC_MAXLEN * 2] = PubKeyY[n];
    }
    for (n = 0; n < SM2_USENAME_LEN; n++) {
      array_in[1 + n + ECC_MAXLEN * 3] = sm2_UerName[n];
    }

    var array_out = this.SendWithDataNoErr(0x32, array_in, KeyPath);
    if (this.lasterror != 0) return this.lasterror;
    if (array_out[0] != 0x20) this.lasterror = USBStatusFail;

    return this.lasterror;
  }

  NT_GenKeyPair(KeyPath) {
    var KEYPAIR = {
      PriKey: null,
      PubKeyX: null,
      PubKeyY: null,
    };
    var array_in = new Uint8Array(SM2_MAX_TRANSE_LEN);
    var n = 0;

    var array_out = this.SendWithDataNoErr(GEN_KEYPAIR, array_in, KeyPath);
    if (this.lasterror != 0) return undefined;
    if (array_out[0] != 0x20) {
      this.lasterror = FAILEDGENKEYPAIR;
      return undefined;
    }
    KEYPAIR.PriKey = array_out.slice(1, 1 + ECC_MAXLEN);
    KEYPAIR.PubKeyX = array_out.slice(1 + ECC_MAXLEN, ECC_MAXLEN * 2 + 1);
    KEYPAIR.PubKeyY = array_out.slice(1 + ECC_MAXLEN * 2, ECC_MAXLEN * 3 + 1);
    return KEYPAIR;
  }

  NT_Get_SM2_PubKey(KeyPath) {
    var SM2_PubKeyInfo = {
      KGx: null,
      KGy: null,
      sm2_UerName: null,
    };
    var array_in = new Uint8Array(SM2_MAX_TRANSE_LEN);
    var n = 0;

    var array_out = this.SendWithDataNoErr(0x33, array_in, KeyPath);
    if (this.lasterror != 0) return this.lasterror;
    if (array_out[0] != 0x20) {
      this.lasterror = USBStatusFail;
      return this.lasterror;
    }

    SM2_PubKeyInfo.KGx = array_out.slice(1, 1 + ECC_MAXLEN * 1);
    SM2_PubKeyInfo.KGy = array_out.slice(
      1 + ECC_MAXLEN * 1,
      1 + ECC_MAXLEN * 2,
    );

    SM2_PubKeyInfo.sm2_UerName = array_out.slice(
      1 + ECC_MAXLEN * 2,
      1 + ECC_MAXLEN * 2 + SM2_USENAME_LEN,
    );

    return SM2_PubKeyInfo;
  }

  NT_Set_Pin(old_pin, new_pin, KeyPath) {
    var array_in = new Uint8Array(SM2_MAX_TRANSE_LEN);
    var n = 0;

    var b_oldpin = Buffer.from(old_pin);
    var b_newpin = Buffer.from(new_pin);
    for (n = 0; n < PIN_LEN; n++) {
      array_in[1 + PIN_LEN * 0 + n] = b_oldpin[n];
      array_in[1 + PIN_LEN * 1 + n] = b_newpin[n];
    }

    var array_out = this.SendWithDataNoErr(SET_PIN, array_in, KeyPath);
    if (this.lasterror != 0) return this.lasterror;
    if (array_out[0] != 0x20) {
      this.lasterror = USBStatusFail;
      return this.lasterror;
    }
    if (array_out[1] != 0x20) {
      this.lasterror = FAILPINPWD;
    }
    return this.lasterror;
  }

  NT_SM2_Enc(inbuf, inlen, KeyPath) {
    var array_in = new Uint8Array(SM2_MAX_TRANSE_LEN);
    var outbuf = new Uint8Array(inlen + SM2_ADDBYTE);
    var n = 0;

    array_in[1] = inlen;
    for (n = 0; n < inlen; n++) {
      array_in[2 + n] = inbuf[n];
    }
    var array_out = this.SendWithDataNoErr(MYENC, array_in, KeyPath);
    if (this.lasterror != 0) {
      return outbuf;
    }
    if (array_out[0] != 0x20) {
      this.lasterror = USBStatusFail;
      return outbuf;
    }
    if (array_out[1] == 0) {
      this.lasterror = FAILENC;
      return outbuf;
    }

    for (n = 0; n < inlen + SM2_ADDBYTE; n++) {
      outbuf[n] = array_out[2 + n];
    }

    return outbuf;
  }

  NT_SM2_Dec(inbuf, inlen, pin, KeyPath) {
    var array_in = new Uint8Array(SM2_MAX_TRANSE_LEN);
    var outbuf = new Uint8Array(inlen - SM2_ADDBYTE);
    var n = 0;

    var b_pin = Buffer.from(pin);
    for (n = 0; n < PIN_LEN; n++) {
      array_in[1 + PIN_LEN * 0 + n] = b_pin[n];
    }
    array_in[1 + PIN_LEN] = inlen;
    for (n = 0; n < inlen; n++) {
      array_in[1 + PIN_LEN + 1 + n] = inbuf[n];
    }
    var array_out = this.SendWithDataNoErr(MYDEC, array_in, KeyPath);
    if (this.lasterror != 0) {
      return outbuf;
    }
    if (array_out[2] != 0x20) {
      this.lasterror = FAILPINPWD;
      return outbuf;
    }
    if (array_out[1] == 0) {
      this.lasterror = FAILENC;
      return outbuf;
    }
    if (array_out[0] != 0x20) {
      this.lasterror = USBStatusFail;
      return outbuf;
    }
    for (n = 0; n < inlen - SM2_ADDBYTE; n++) {
      outbuf[n] = array_out[3 + n];
    }

    return outbuf;
  }

  sub_NT_Sign(cmd, inbuf, pin, KeyPath) {
    var outbuf = new Uint8Array(ECC_MAXLEN * 2);
    var array_in = new Uint8Array(SM2_MAX_TRANSE_LEN);
    var n = 0;

    var b_pin = Buffer.from(pin);
    for (n = 0; n < PIN_LEN; n++) {
      array_in[1 + PIN_LEN * 0 + n] = b_pin[n];
    }
    for (n = 0; n < 32; n++) {
      array_in[1 + PIN_LEN + n] = inbuf[n];
    }
    var array_out = this.SendWithDataNoErr(cmd, array_in, KeyPath);
    if (this.lasterror != 0) {
      return outbuf;
    }
    if (array_out[1] != 0x20) {
      this.lasterror = FAILPINPWD;
      return outbuf;
    }
    if (array_out[0] != 0x20) {
      this.lasterror = USBStatusFail;
      return outbuf;
    }
    for (n = 0; n < ECC_MAXLEN * 2; n++) {
      outbuf[n] = array_out[2 + n];
    }

    return outbuf;
  }

  NT_Sign(inbuf, pin, KeyPath) {
    return this.sub_NT_Sign(0x51, inbuf, pin, KeyPath);
  }

  NT_Sign_2(inbuf, pin, KeyPath) {
    return this.sub_NT_Sign(0x53, inbuf, pin, KeyPath);
  }

  NT_Verfiy(inbuf, InSignBuf, KeyPath) {
    var array_in = new Uint8Array(SM2_MAX_TRANSE_LEN);
    var n = 0;

    for (n = 0; n < ECC_MAXLEN; n++) {
      array_in[1 + n] = inbuf[n];
    }
    for (n = 0; n < ECC_MAXLEN * 2; n++) {
      array_in[1 + ECC_MAXLEN + n] = InSignBuf[n];
    }
    var array_out = this.SendWithDataNoErr(YTVERIFY, array_in, KeyPath);
    if (this.lasterror != 0) return false;
    var outbiao = array_out[1] != 0;
    if (array_out[0] != 0x20) {
      this.lasterror = USBStatusFail;
      return false;
    }

    return outbiao;
  }

  YT_GenKeyPair(KeyPath) {
    var n;
    var KeyPairInfo = {
      PriKey: '',
      PubKeyX: '',
      PubKeyY: '',
    };
    var KEYPAIR = this.NT_GenKeyPair(KeyPath);
    if (this.lasterror) return KeyPairInfo;
    KeyPairInfo.PriKey = this.ByteArrayToHexString(KEYPAIR.PriKey, ECC_MAXLEN);
    KeyPairInfo.PubKeyX = this.ByteArrayToHexString(
      KEYPAIR.PubKeyX,
      ECC_MAXLEN,
    );
    KeyPairInfo.PubKeyY = this.ByteArrayToHexString(
      KEYPAIR.PubKeyY,
      ECC_MAXLEN,
    );

    return KeyPairInfo;
  }

  Set_SM2_KeyPair(PriKey, PubKeyX, PubKeyY, SM2_UserName, KeyPath) {
    var b_PriKey = this.HexStringToByteArray(PriKey);
    var b_PubKeyX = this.HexStringToByteArray(PubKeyX);
    var b_PubKeyY = this.HexStringToByteArray(PubKeyY);

    var b_SM2UserName = Buffer.from(SM2_UserName);

    return this.NT_Set_SM2_KeyPair(
      b_PriKey,
      b_PubKeyX,
      b_PubKeyY,
      b_SM2UserName,
      KeyPath,
    );
  }

  Get_SM2_PubKey(KeyPath) {
    var PubKeyInfo = {
      PubKeyX: '',
      PubKeyY: '',
      sm2UserName: '',
    };

    var SM2_PubKeyInfo = this.NT_Get_SM2_PubKey(KeyPath);

    PubKeyInfo.PubKeyX = this.ByteArrayToHexString(
      SM2_PubKeyInfo.KGx,
      ECC_MAXLEN,
    );
    PubKeyInfo.PubKeyY = this.ByteArrayToHexString(
      SM2_PubKeyInfo.KGy,
      ECC_MAXLEN,
    );
    PubKeyInfo.sm2UserName = new Buffer(SM2_PubKeyInfo.sm2_UerName).toString();
    return PubKeyInfo;
  }

  SM2_EncBuf(InBuf, inlen, KeyPath) {
    var n,
      temp_inlen,
      incount = 0,
      outcount = 0;
    var temp_InBuf = new Uint8Array(MAX_ENCLEN + SM2_ADDBYTE);
    var OutBuf = Buffer.alloc(0);
    //InBuf.copy(OutBuf);
    while (inlen > 0) {
      if (inlen > MAX_ENCLEN) temp_inlen = MAX_ENCLEN;
      else temp_inlen = inlen;
      for (n = 0; n < temp_inlen; n++) {
        temp_InBuf[n] = InBuf[incount + n];
      }
      var temp_OutBuf = this.NT_SM2_Enc(temp_InBuf, temp_inlen, KeyPath);
      if (this.lasterror) return OutBuf;
      OutBuf = Buffer.concat([OutBuf, temp_OutBuf]);
      inlen = inlen - MAX_ENCLEN;
      incount = incount + MAX_ENCLEN;
      outcount = outcount + MAX_DECLEN;
    }

    return OutBuf;
  }

  SM2_DecBuf(InBuf, inlen, pin, KeyPath) {
    var temp_inlen,
      n,
      incount = 0,
      outcount = 0;
    var temp_InBuf = new Uint8Array(MAX_ENCLEN + SM2_ADDBYTE);
    var OutBuf = Buffer.alloc(InBuf.length);
    //var b=new Buffer(InBuf)
    //b.copy(OutBuf);
    var OutBuf = Buffer.alloc(0);
    while (inlen > 0) {
      if (inlen > MAX_DECLEN) temp_inlen = MAX_DECLEN;
      else temp_inlen = inlen;
      for (n = 0; n < temp_inlen; n++) {
        temp_InBuf[n] = InBuf[incount + n];
      }
      var temp_OutBuf = this.NT_SM2_Dec(InBuf, temp_inlen, pin, KeyPath);
      if (this.lasterror) return OutBuf;
      OutBuf = Buffer.concat([OutBuf, temp_OutBuf]);
      inlen = inlen - MAX_DECLEN;
      incount = incount + MAX_DECLEN;
      outcount = outcount + MAX_ENCLEN;
    }
    return OutBuf;
  }

  SM2_EncString(InString, KeyPath) {
    var InBuf = Buffer.from(InString);
    var OutBuf = this.SM2_EncBuf(InBuf, InBuf.length, KeyPath);
    if (this.lasterror) return OutBuf;
    return this.ByteArrayToHexString(OutBuf, OutBuf.length);
  }

  SM2_DecString(InString, pin, KeyPath) {
    var InBuf = this.HexStringToByteArray(InString);

    var OutBuf = this.SM2_DecBuf(InBuf, InBuf.length, pin, KeyPath);

    return OutBuf.toString();
  }

  YtSetPin(old_pin, new_pin, KeyPath) {
    return this.NT_Set_Pin(old_pin, new_pin, KeyPath);
  }

  Sub_YtSign(cmd, msg, pin, KeyPath) {
    var OutSign;

    var MsgHashValue = sm3(msg);
    var Inbuf = new Buffer.from(MsgHashValue, 'hex');
    var OutBuf = this.sub_NT_Sign(cmd, Inbuf, pin, KeyPath);
    if (this.lasterror != 0) return OutSign;
    OutSign = new Buffer(OutBuf).toString('hex');
    return OutSign;
  }

  YtSign(msg, pin, KeyPath) {
    return this.Sub_YtSign(0x51, msg, pin, KeyPath);
  }

  YtSign_2(msg, pin, KeyPath) {
    return this.Sub_YtSign(0x53, msg, pin, KeyPath);
  }

  CheckKeyByFindort_2() {
    //使用普通算法查找指定的加密锁
    var DevicePath = ''; //用于储存加密锁的路径
    DevicePath = this.FindPort_2(0, 1, 1580180348);
    return this.lasterror;
  }

  //使用带长度的方法从指定的地址中读取字符串
  ReadStringEx(addr, DevicePath) {
    var nlen;
    //先从地址0读取以前写入的字符串长度
    var OutData = this.YReadEx(addr, 1, '59AB9835', '90B7AE6E', DevicePath);
    if (this.lasterror != 0) return '';
    nlen = OutData[0];
    //再读取相应长度的字符串
    return this.YReadString(addr + 1, nlen, '59AB9835', '90B7AE6E', DevicePath);
  }

  //使用从储存读取相应的数据的方式来检查是否存在指定的加密锁
  CheckKeyByReadEprom() {
    var n, ret;

    //@NoUseCode_data return 1;//如果没有使用这个功能，直接返回1
    for (n = 0; n < 255; n++) {
      var DevicePath = this.FindPort(n); //用于储存加密锁的路径
      if (this.lasterror != 0) return this.lasterror;
      var outString = this.ReadStringEx(0, DevicePath);
      if (this.lasterror == 0 && outString == 'BJWK') return 0;
    }
    return -92;
  }

  //使用增强算法一检查加密锁，这个方法可以有效地防止仿真
  CheckKeyByEncstring() {
    //推荐加密方案：生成随机数，让锁做加密运算，同时在程序中使用代码做同样的加密运算，然后进行比较

    var n, ret;

    var InString;

    //@NoUseKeyEx return 1;//如果没有使用这个功能，直接返回1
    var number1 = Math.floor(Math.random() * 65535);
    var number2 = Math.floor(Math.random() * 65535);

    InString = number1.toString() + number2.toString();

    for (n = 0; n < 255; n++) {
      var DevicePath = this.FindPort(n); //用于储存加密锁的路径
      if (this.lasterror != 0) return this.lasterror;
      if (this.Sub_CheckKeyByEncString(InString, DevicePath) == 0) return 0;
    }
    return -92;
  }

  Sub_CheckKeyByEncString(InString, DevicePath) {
    //使用增强算法一对字符串进行加密

    var outString = this.EncString(InString, DevicePath);
    if (this.lasterror != 0) return this.lasterror;
    var outString_2 = this.StrEnc(InString, '51213AA3772EFADA66525263FDA3E8FB');
    if (outString_2.toUpperCase() == outString.toUpperCase()) {
      //比较结果是否相符
      return 0;
    }

    return -92;
  }

  //?使用增强算法二检查加密锁，这个方法可以有效地防止软复制
  CheckKeyByEncstring_New() {
    var n, ret;
    var myrnd = Math.floor(Math.random() * 500);
    var EncInString = [
      '10985',
      '12168',
      '12599',
      '13697',
      '25760',
      '6984',
      '17216',
      '8078',
      '26112',
      '30863',
      '10034',
      '8288',
      '32147',
      '961',
      '12263',
      '10089',
      '9474',
      '30684',
      '13401',
      '6074',
      '31510',
      '8327',
      '22946',
      '27141',
      '23995',
      '3073',
      '31997',
      '28318',
      '9210',
      '23852',
      '15811',
      '12149',
      '30716',
      '15755',
      '10094',
      '29212',
      '20750',
      '28480',
      '31639',
      '22983',
      '3479',
      '32524',
      '7163',
      '10566',
      '11555',
      '5715',
      '5233',
      '9483',
      '10842',
      '27923',
      '17652',
      '5418',
      '29959',
      '23539',
      '11167',
      '26450',
      '3094',
      '3634',
      '20138',
      '28887',
      '14221',
      '21426',
      '18033',
      '20651',
      '25241',
      '4855',
      '26476',
      '29024',
      '5507',
      '23328',
      '3128',
      '11048',
      '4022',
      '5618',
      '32651',
      '1492',
      '442',
      '22988',
      '1603',
      '6870',
      '26426',
      '23475',
      '2391',
      '5953',
      '257',
      '328',
      '24546',
      '24006',
      '28407',
      '4811',
      '14623',
      '18617',
      '27176',
      '3361',
      '9831',
      '3082',
      '7870',
      '5066',
      '17715',
      '14156',
      '9729',
      '745',
      '2336',
      '22448',
      '8284',
      '8511',
      '9700',
      '14857',
      '28505',
      '29230',
      '6493',
      '19656',
      '4003',
      '10170',
      '21889',
      '8705',
      '4866',
      '13443',
      '2670',
      '4452',
      '14946',
      '32203',
      '4188',
      '31298',
      '12236',
      '11639',
      '29092',
      '9617',
      '24681',
      '9221',
      '5314',
      '18399',
      '30341',
      '2713',
      '1615',
      '9057',
      '29578',
      '1268',
      '25349',
      '18918',
      '27136',
      '889',
      '25022',
      '32482',
      '22419',
      '13609',
      '32116',
      '14696',
      '7948',
      '6567',
      '16194',
      '17960',
      '8788',
      '13109',
      '10337',
      '2421',
      '31863',
      '22708',
      '15402',
      '24895',
      '23454',
      '10152',
      '10777',
      '10011',
      '31507',
      '5681',
      '6087',
      '21049',
      '15680',
      '9489',
      '2798',
      '14700',
      '26031',
      '12715',
      '29544',
      '29989',
      '29451',
      '26624',
      '21807',
      '24951',
      '6429',
      '21683',
      '4702',
      '16404',
      '23246',
      '5894',
      '21805',
      '31309',
      '17450',
      '13019',
      '6648',
      '790',
      '17498',
      '691',
      '22839',
      '22782',
      '10153',
      '18864',
      '20870',
      '10298',
      '12671',
      '26005',
      '29086',
      '3226',
      '22119',
      '8389',
      '25178',
      '29584',
      '5644',
      '9279',
      '12466',
      '7727',
      '30006',
      '2472',
      '6082',
      '17193',
      '6097',
      '3392',
      '27330',
      '20687',
      '31461',
      '24552',
      '7950',
      '20244',
      '20126',
      '6438',
      '30238',
      '24970',
      '28741',
      '18712',
      '18318',
      '26978',
      '1093',
      '10883',
      '27415',
      '18287',
      '12326',
      '29894',
      '17044',
      '15907',
      '29843',
      '19942',
      '25597',
      '29582',
      '10072',
      '23683',
      '25453',
      '4966',
      '3419',
      '31200',
      '15647',
      '4345',
      '5289',
      '991',
      '24427',
      '2363',
      '11883',
      '20225',
      '21709',
      '17597',
      '18667',
      '14440',
      '3551',
      '22963',
      '27027',
      '22488',
      '19288',
      '28140',
      '26349',
      '20913',
      '10262',
      '6365',
      '17060',
      '18677',
      '17168',
      '26006',
      '9089',
      '28999',
      '2402',
      '29898',
      '28525',
      '16617',
      '8260',
      '16074',
      '1397',
      '17085',
      '28433',
      '30089',
      '6080',
      '2116',
      '18756',
      '1689',
      '9625',
      '15264',
      '14454',
      '15659',
      '5482',
      '20885',
      '26209',
      '1043',
      '28349',
      '23426',
      '9951',
      '18368',
      '13372',
      '31084',
      '8683',
      '30789',
      '23986',
      '27635',
      '7581',
      '11095',
      '29191',
      '18010',
      '26672',
      '24132',
      '16712',
      '16515',
      '25087',
      '22528',
      '16028',
      '10479',
      '10115',
      '11037',
      '31309',
      '30400',
      '23382',
      '22476',
      '15304',
      '31673',
      '4146',
      '3552',
      '15252',
      '13885',
      '21233',
      '3787',
      '32092',
      '17227',
      '21645',
      '12189',
      '18923',
      '28807',
      '13345',
      '31499',
      '18730',
      '28211',
      '26853',
      '29541',
      '15395',
      '8497',
      '19509',
      '29854',
      '22272',
      '5378',
      '17290',
      '13896',
      '15115',
      '3529',
      '2686',
      '28052',
      '4271',
      '14919',
      '7371',
      '3926',
      '16756',
      '1503',
      '16459',
      '12797',
      '20997',
      '2707',
      '12024',
      '3997',
      '23596',
      '8964',
      '24812',
      '10216',
      '10452',
      '7285',
      '30306',
      '560',
      '27142',
      '2247',
      '16819',
      '3941',
      '5356',
      '12413',
      '29016',
      '11292',
      '23504',
      '9401',
      '23021',
      '17029',
      '18460',
      '28988',
      '24619',
      '3187',
      '29786',
      '28265',
      '749',
      '30039',
      '26165',
      '13122',
      '1323',
      '7237',
      '2166',
      '10088',
      '14336',
      '30188',
      '17671',
      '13598',
      '25767',
      '3745',
      '16113',
      '6981',
      '22136',
      '27731',
      '11361',
      '24416',
      '1264',
      '4248',
      '20637',
      '24464',
      '23973',
      '6814',
      '5651',
      '1177',
      '11860',
      '2361',
      '18506',
      '5083',
      '11991',
      '7386',
      '28141',
      '8537',
      '11046',
      '22932',
      '17095',
      '8628',
      '19804',
      '10521',
      '20929',
      '7215',
      '1972',
      '7354',
      '12005',
      '31915',
      '7815',
      '20330',
      '20829',
      '1452',
      '21070',
      '26555',
      '3443',
      '25168',
      '10661',
      '14814',
      '11921',
      '22622',
      '23365',
      '2470',
      '12610',
      '6709',
      '22536',
      '27780',
      '7470',
      '14552',
      '29928',
      '19340',
      '32544',
      '13800',
      '13568',
      '1390',
      '772',
      '13736',
      '13193',
      '12412',
      '11744',
      '20729',
      '11740',
      '31912',
      '14305',
      '1887',
      '11637',
      '13702',
      '1617',
      '20729',
      '20973',
      '25670',
      '17815',
      '20619',
      '15102',
      '4540',
      '9025',
      '9591',
      '4738',
      '10327',
      '10230',
      '23998',
      '13939',
      '30251',
    ];
    var EncOutString = [
      '878DEF9C2750C08E',
      '34F08EA25E66AF2C',
      'FFEF544FD64708A1',
      'AD7ACF616EA0C6B4',
      '9965D63648972263',
      '6E5A94C8C15F85FB',
      '6B0C1BD60D605D18',
      '5F488BBC6976D726',
      'E0AB110E85F38D11',
      'C689688725A8B410',
      'ACEB008A0070F860',
      '6F93ABA566751075',
      'BD2AE21A63E285EF',
      '161274ADF6E1B588',
      '62DEC38DA3E25ED8',
      '0EA320567B845F5E',
      'C5737AA3BD39F403',
      '885B1D3010F673D1',
      '1950556C3403BA66',
      '92549DC721D3C625',
      'D9A149C272208C97',
      '8588CEE4784B29AD',
      'A191FCD12C03858D',
      'CC5D65A9A4E4D800',
      '1219556E5F3880B3',
      '40C6FF2862B09998',
      '1363EFDE28E3806E',
      '1D6D3D70F81CB656',
      'E5B0A4853FC7D393',
      'E470751CCD482D95',
      '3C52A1C384937C94',
      'CC3699DC8D966955',
      '8911BE57680799D5',
      '553D00950D50808F',
      '9ECE206A15CB0FE8',
      'F34D07271504974C',
      '90941D27F993C453',
      'EC1122A1208EAF19',
      'D75D358825069804',
      '72F8456943573C06',
      '194D6DFE132CE569',
      '1E6A9613BF88B8B6',
      '391D7D6AB2C63FE1',
      'FA9A891C6BD45F2F',
      'E35DAABFCB249A04',
      'A2B2AF4A8DA9602C',
      '1A3EAC6552753E69',
      '8290CAE4FFFBDF83',
      '003246964B0008F9',
      '778B5804C02D09A1',
      '281C2D8F19C2A696',
      'AB2541B975BB31EE',
      'AAD0A9879130C67D',
      '8CBED78274739300',
      'BA6066395902D9F2',
      '7D051E33E77876A6',
      'E115736AB931CC74',
      'B8DC42BA19FE9446',
      'E778024025552601',
      'E302E873B8E559D7',
      '6847EC8ADF86AF46',
      'C2FDA99BCC7C53E7',
      '959CD1F794454001',
      'C2E9C1F49184ECFF',
      '18649C2767675A6D',
      '75516E07B9DD8478',
      '0BCA35C464A7E09C',
      '626E07D586E2A1D9',
      'E471BA4FA59F65B0',
      '6AFC20443767AC91',
      '32D390E75862A7CF',
      '70E9BDCE3D2F8988',
      '9CFA8F15BECFA3C4',
      '476140CA007FE08B',
      '2B14F8C2BC8343E9',
      'BA7C9D14F47ED9E0',
      '21A04CE5381C5C5E',
      'D73AD2D4B7EDFA7D',
      '25AABD2A7B68FE27',
      'E9B34A7010C9A96C',
      '7ABD1512ECE8F1E0',
      '87447BBB6C3660D8',
      'D112FE0734BB8FD1',
      '8109D39DCAF491A5',
      'EF3760E7FC9EF005',
      '03B92B566BDB2942',
      '454C24AD7711E020',
      '35329D7AC8741156',
      '926A1A71EE32399B',
      '001C272EFF6151D7',
      '83F31817A7A56023',
      '3EA615D241CFA708',
      'F917DCCEA92A01F9',
      '899E7ABD016DF5D1',
      '744805A2F1CA6FAC',
      '90103074541E546D',
      'F5FBF25F89E1297F',
      'CB044AA12F298656',
      '43071251C451E28F',
      '2C6CE4E7BB4CE9FE',
      '88F46FE2F029A5FE',
      '32021D3F16196FC6',
      '13DB5907DD800FB7',
      'FFDDEB0F10F09363',
      'ACA8DB42141A0DED',
      '59C4BFEF8B5D7A7A',
      '1E1D585912D7140D',
      'A13B29895305E086',
      '838C0E4520EAEBAA',
      '79B20B5C0317ADFF',
      'B4344D27BAB702D5',
      '5ACC35BF6B93FE46',
      '074F1D8FFA8CB26F',
      'E003FB5875215805',
      '4F3A90576EABE161',
      '212733A545C49343',
      'C4E5E9C0F295B120',
      'EE99DD806E56C68B',
      '3D550AC60B1746AE',
      '600EB88CF1D69FDD',
      '382D79031E69B9AF',
      '718F052346B48237',
      'E0927FE687D759AD',
      'EE96030B9FF68174',
      '5EDEA451363DB0B3',
      'E7C09F6205C03448',
      'C9CEB032651610CD',
      '8BB53B57F78459AA',
      'AFE38F625D7ED793',
      'FE14619C10F9CBF5',
      'C56E64006D030AA4',
      '4F003AFEC492B73B',
      'BED074A6C828E4C5',
      'B42D02A56D2385A0',
      'A2B9B9F68600035B',
      'F5C5621491F40179',
      '400E44BF55197AC8',
      '0AA37D1CF7ECC4FB',
      'C05EEA2F5C17F2DA',
      '21E89A1DAE2AEC3E',
      '8FD316BD697650EB',
      '66AC55697E482854',
      '9240A2CB565B98B9',
      '77C78E9C8A3C8F42',
      'DA09D149D6C07D0D',
      '77BB0D255816DF42',
      'E0DCD8706308D624',
      'ACDAFAEB63167EE9',
      'EE0E1D8471705B77',
      '47EB03B03BAE7AD0',
      'A6D5470D99981D94',
      'D831B17E28F14CCB',
      '49AD76FD33BB15E5',
      '67729EE06B5FAE62',
      'B3444DC28524FFC7',
      'C6B4FDDF2323E186',
      'EBB4D35506D4F6C2',
      '15DB34B802DB496D',
      '4EEA3567E05BCD38',
      'BFB7CD9B2DF5CECF',
      'BA71172B613B49CA',
      'BFCB4E271EC716A4',
      'AC4B30F337F3FF02',
      '2946088429089385',
      '253721C3B2F39CCB',
      'A7E95CDC52827579',
      '1FAEB52E228F2049',
      'E011DF425D1922C5',
      '1D26F000D52B0994',
      '93F412D2802F1016',
      'B95651CCC30C12DF',
      'D678699AF90E2C8F',
      'C8645EDA4D49CC87',
      '32D9E69700AF34C2',
      'F4C4E8017540ECBC',
      'B56D7547155C605A',
      'DEF72DA1D6AB2FFE',
      '4632837ACBA45360',
      '40A2400B5DCC927A',
      '5F76449FE80FDAF4',
      '5C729AEEFC1CA61E',
      '536A1E6F3E2219F4',
      '10C9B6B44A6CF653',
      '0019A9C7446A7B0D',
      '6A8CC2D0E94A72F7',
      'C16C63183DE0126C',
      '109E606881FC046A',
      '1990364E455F4D05',
      '8927F7EAEF9B17DE',
      '6E4BCF7E6AABE515',
      '9EF387B86F40171B',
      'EF2539DA4DCB4F95',
      'DDAB638985A0C9BE',
      '5D59531479DD64EF',
      'F7D83C9E4490B7CA',
      'C328CFCDBAC38A90',
      'D723ECB6EFA3D476',
      'F8806443AB8C9DEE',
      '906059AAC5652F76',
      'B6B3EB6491B495B0',
      '78ABB697FB012E32',
      '07B3EB2877E8F2AC',
      '3BD41954E53565B3',
      '677D284507C3EA75',
      '8B216B40E31F058D',
      '9A3EA03886066D93',
      'BC606DF73640BC1E',
      'B8E5FDA52ADB80FC',
      '9A4C8CE92F34B81B',
      '9AB0AB45D56D01C2',
      'AE388688FCCA9568',
      '6F2061C125E78DDD',
      'C53D46621CE0038C',
      '573575F228000CEF',
      '1E872008E41F9343',
      '40BF4EB0305DDDB8',
      '1D42A9817BC80CD0',
      '76375979BC0444FA',
      '1F57E0191B7D17D6',
      '715D34EF4A29DBB2',
      'C3B6F470D40CF21E',
      '138CEF529C5567B3',
      '18309D9043EA66EB',
      '067B9C01B777F560',
      '04B2C332C55AB21D',
      '3DD42E61AF396085',
      '2F26E6294174F01D',
      '54DC0865F923C07D',
      '430F03EE069AF41F',
      'E32EC5DBD96CD20D',
      'D884B606E3543E44',
      '23CFFCDEF6E986B6',
      '1700BFE9A412D75D',
      '040F04501DFBE931',
      '27CECB5F2552450B',
      '7CF22FB91DE86854',
      '1415C140FB9B6FB7',
      '8A251E4F52684E87',
      '4C357D4477CEC510',
      'AA25890644EA350D',
      '662F9CD7C3BBDB4D',
      'A58CBA6B6CD87E10',
      '7997A33FBEE99DB8',
      '91376A0E38B9B99E',
      '14CC5317858B55B4',
      '410358D8B2F5AD05',
      'D3AD0C271507FA48',
      'B6F94C517B355C3E',
      '196CBD99247D945F',
      'A4CCD88F8A9BC827',
      '366B7339F6350607',
      '8E32D4D0FF56A752',
      'A6BE161749F4AEFC',
      '474B9E6ECFB39A60',
      'FB7ECCE97044E67C',
      '482710DC616C7EED',
      'C478DD72AADED448',
      'C8D4431C722AE1A1',
      '4A21F45121EA95E6',
      '687ADA58051FD99F',
      'BEE693511544A72F',
      'AC2AE151DAD7C124',
      'FFF32439024C8DBD',
      'A7E79BFB38441B0C',
      '1AA7841390B40753',
      '04AA01177398D7E7',
      'A9FADD16AFB66488',
      '9B497CD1BDBFC936',
      'BDA5B40C91A5892F',
      '1CE760BE58BA390F',
      '360F261145AF325F',
      'E7423BA066C217DA',
      'E6BEC79D9CE5CE70',
      'EE82B2CA22C5EAB8',
      '4CD6C08682F9BBF0',
      '69F42D093ACDA320',
      '87FFA8F5A075E379',
      'FE8F23DD99464B59',
      '48BE63B1B924088C',
      'C0EE01C27964BA86',
      'FF591FB8A79073AA',
      'E72394191DE1E899',
      '34E97FC7E748A697',
      '2358323E19D4FB33',
      '2E7226F02521DE1C',
      'ADB78A6930165871',
      'DF672AFB8F7F1ABE',
      '5A6A4B129F4C9E24',
      '171438DFB208ADC5',
      'F00AB7CECA9328DC',
      '9FFF55C437532F76',
      'E201EE7E9415EF36',
      'C9AE05C99201078A',
      'F15CF0BE2089D5E9',
      'CC5A2E7FA09B5F34',
      '0BB718D4C99709B3',
      '228766BCC0092B35',
      '4CD1F77781505113',
      'A5822421A0721274',
      '66B348617ABD2720',
      'C5577E2E84EF4B8B',
      '3A49D2B0C471AF29',
      'C2ECC41B957F41F3',
      '0934BA9A969483BC',
      '144C264E2823BF27',
      '1E21D66E569400E5',
      '0418D046CEBB4732',
      'C043075CC8BB9BBA',
      'E55F56ADBE502595',
      'D524ED5CED2B46BC',
      'C152E99A66CAF8B2',
      '68791867159E1D91',
      'DD2EBF5594F6EF5B',
      'AFE9955FED61EF98',
      'D0A0298DB7237FBA',
      '3493EB26D953783C',
      'A1C7446ACC7A2CC7',
      '3C17DD84638164E8',
      'E3EBB7507E3B2E97',
      'E74CBEF28D07B772',
      'AF5880FF77D6A3F9',
      '61624F3FE8A3C146',
      'FD7D62B3B7C75C9D',
      '22BC0B98C4995F07',
      '1990364E455F4D05',
      '9924DA60F07501D2',
      '463F6F8D36F266F4',
      '199ADFBC5C178182',
      '898E1BDA0589A8FE',
      'CDA4A115A0E23815',
      '451374914AACB53F',
      'BD1454D6F0B553ED',
      '1CD94221C6CCD4E3',
      '26A66E370B5281BB',
      'F8D15443C1C468E4',
      '2AD0AEDF9DD507A3',
      '8FFA956775DE60E1',
      '39344FC07DB215E2',
      '80D6EA9BEEEC146F',
      '2AD444E93268C9CF',
      'A5A3AF1AB22E0EF8',
      'B97B0344C263BF35',
      '3B04CBB8EA48DFC4',
      '64CCC786B885C0AB',
      '7ACAF8FF005388E7',
      '205D0521DDC96C88',
      '57925D11BF99A5C5',
      'E03A448C8207BC15',
      'C9AFC3D8B3C2F0B7',
      '8736A04F69CFFD57',
      'AB6AED9F99493A66',
      '226808B6DD005DC3',
      '690982F95CDEC37C',
      '7E90346637D4E6A8',
      '6789240F3395E591',
      'A4D995E898FCE417',
      '2DCBF9A601F0FD7E',
      'EE9319E4CA809C5D',
      '20CD98F6DB431A9B',
      '84B0AF076D44EC62',
      '4AD1CA5840EA282D',
      '2B761F337296EB75',
      '2F5EDAC3DB8DD46E',
      'B435FF2A5538A870',
      '403FB1BC2276E459',
      '2C85661B6C0D0957',
      '783D07EF8AE80C71',
      '63D05816E18BE2D7',
      'CEA2E64926DEE738',
      '320D3A303D6D1288',
      '40FA6C2C4B419213',
      'EF5B13F6F851223B',
      'ACAABDCE65E7F20E',
      '123415A6BD5A5BA0',
      '17497E122E42EEF0',
      '1B47C453B85F51BE',
      '238C6FE102AFCBB2',
      '396C7994EA5039C0',
      'F1B3BAAC65FC4712',
      '0C6EE87FB6993B16',
      '0AABAE0D33BBDF37',
      '08CB4B81FF54857B',
      '4DDE6CFF05C0ECDE',
      '8217779AB9051C5E',
      '433E71E6409451DD',
      'CA32145D4E688DE9',
      '393DA5F461CC5153',
      '4085A0554EC24676',
      '88C71301BA41664F',
      '5E186BED98F96604',
      '0E63D5A1CCE9BE7F',
      'D12F54524CDBBD95',
      '2B3E400BD61A7949',
      '0285FB5E47ECB834',
      '7F85DD5F950A0015',
      'EB1F469E9A4C2BBF',
      '95A7B8B4B6519538',
      'D363A50CE6D43E07',
      '8406FE256C36E246',
      'CA6931AD299274B9',
      '78644B02B90D1A91',
      '13020F6F98EB18E4',
      '689F8C11D2C29F44',
      '3F3F82BADF459500',
      'A8FCB412AC623C95',
      'FCFEE84785433909',
      'A0F1A1541785E9FA',
      '1B85FF9287599196',
      'B080E7F47DE9B9AE',
      '7D4DC854F7F595A2',
      '0D798288480BE8FA',
      'CD37F7400C3F26C2',
      '09A51D1FC09237B5',
      'E33F42C56F5ED7EE',
      'E4384C8A33B05911',
      'D1E64626BA66B7D2',
      'FAF374AF164BF838',
      '02D0DC7806F0F0FE',
      'B6077EC3347B3EE3',
      '01A74200DEBECA93',
      'AF38DC5D3E183990',
      '5009D9E723509A35',
      '5E013FA1713F8312',
      'C49EC28F08675787',
      'B2CA240E3D963AAE',
      '2C8E69C9D3557331',
      '48418358EC871308',
      '87AE09DAFDE809F6',
      '8B8BA6E4D66D44A9',
      '76091B691AD078F9',
      '209708CF4CBF7EAE',
      'C17D026D705D3292',
      '6E7572052BCB8E21',
      '5ACFFAE189F68F85',
      '4D62652041912963',
      'B6E11A056536FFCF',
      '3C1D96991D8E3D85',
      '0081E5696C2F7A43',
      '8D7701BDA96E323F',
      '987DC08AE33DC7C4',
      '7D41E4A2279A6A8B',
      '20A9F69879E4BD2C',
      'ED7B820BCD9690C3',
      '46A51C3FC839F84F',
      '168A5406BAB502BD',
      'F8B65EAA30EAB23C',
      'AD220DC3DE525371',
      'C8E47DA3B7B5EE8F',
      '58492E7DDB435D93',
      '96EDEE6944525DD9',
      'E365D5B4F3AEA0CE',
      'EE1509EB6FB28D4B',
      'D8A28AE9B2204691',
      '6CD31CF7BBB33460',
      '8928F1091DFFC812',
      'B031B46E382229AF',
      'AC16A5712D5307F9',
      '4752DAA49DD28B42',
      '9F304BFE42104FAC',
      '91D03E98C5C680FF',
      'A7E92C22080D3409',
      '7A175FEE27E7B0B5',
      '33895DC92F0B036B',
      '79D46201B26020B8',
      'B5026E599D55009B',
      'E52DAEFD15C9C01A',
      '0AECC0FBA5343A83',
      '819B8EC240B44770',
      'FF5075AF8E4D6631',
      '6F11255D9900B8C1',
      'A7BEBA6FC9A93B2E',
      '9469DD5BA978BD4E',
      '7BAE8084D776C7F9',
      'D22DEF9ACBE81DFC',
      '3E4FE50D6401FA57',
      'E7DCAFCAC0396715',
      '956C3C2E6FF0CCC7',
      '8F706477F7867790',
      'CA91533C083B1F05',
      'C3A3E9689830C257',
      'C6EB45D0136B00C6',
      '477E91023E46EE34',
      'B4856157E6A62294',
      '2AACD5C84C96C099',
      '3196EEE16FB0306D',
      '8F706477F7867790',
      '299D5C1B7DAD9890',
      '185B68DA8911E71C',
      '8EFEA5C9E9A1FFEB',
      'DA78DC41BC155F62',
      '08ABF2C5DF358844',
      'F13075EA2E27EDBC',
      '04791DABDCD69121',
      'E63E126A265E2807',
      '1720B31D542CBAF1',
      'ECDB2BCDB2DE9BEE',
      '8D7B59092A37B3B0',
      '740629F42C790E1C',
      '2FF4AF9F3D101894',
      'B7C98BDC67139B7C',
    ];
    //@NoUseNewKeyEx return 1;//如果没有使用这个功能，直接返回1
    //@NoSupNewKeyEx  return 2;//如果没有使用这个功能，直接返回2

    var mEncInString = EncInString[myrnd];
    var mEncOutString = EncOutString[myrnd];
    for (n = 0; n < 255; n++) {
      var DevicePath = this.FindPort(n); //用于储存加密锁的路径
      if (this.lasterror != 0) return this.lasterror;

      var outString = this.EncString_New(mEncInString, DevicePath);
      if (
        this.lasterror == 0 &&
        outString.toUpperCase() == mEncOutString.toUpperCase()
      )
        return 0;
    }
    return -92;
  }
}

//vid,pid
SoftKey.VID = 0x3689;
SoftKey.PID = 0x8762;
SoftKey.PID_NEW = 0x2020;
SoftKey.VID_NEW = 0x3689;
SoftKey.PID_NEW_2 = 0x2020;
SoftKey.VID_NEW_2 = 0x2020;

export default SoftKey;
